package com.vdg.fps.data;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.security.spec.EncodedKeySpec;
import java.util.ArrayList;

import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import android.content.Context;
import android.graphics.Bitmap.Config;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.util.Xml;
import android.util.Xml.Encoding;
import android.widget.Toast;

import com.facebook.HttpMethod;
import com.vdg.fps.app.FPSManagerment.TimeOutRunable;
import com.vdg.fps.config.ErrorCode;
import com.vdg.fps.config.FPSConfig;
import com.vdg.fps.listener.OnHttpResponse;
import com.vdg.fps.listener.OnPostResultListener;
import com.vdg.fps.listener.OnRequestListnener;
import com.vdg.fps.ulti.FaceBookHTTPRequest;
import com.vdg.fps.ulti.Utilities;

public class FaceBookAccount implements Serializable {
	private String mID;
	private String mToken;
	private long mTokenExpires;
	private String mUserName;
	private FaceBookCookie mCookies;
	private long mLastPost;
	private long mCookiesExpires;
	private AccountProxy mProxy;
	private static String TAG = "FaceBookAccount";

	public String getID() {
		return mID;
	}

	public void setID(String mID) {
		this.mID = mID;
	}

	public String getToken(OnRequestListnener listener) {
		if (System.currentTimeMillis() < mTokenExpires) {
			return mToken;
		} else {
			getAcceToken(listener);
		}
		return mToken;
	}

	public void setToken(String mToken) {
		this.mToken = mToken;
	}

	public long getTokenExpires() {
		return mTokenExpires;
	}

	public void setTokenExpires(long mTokenExpires) {
		this.mTokenExpires = mTokenExpires;
	}

	public String getUserName() {
		return mUserName;
	}

	public void setUserName(String mUserName) {
		this.mUserName = mUserName;
	}

	public FaceBookCookie getCookies() {
		return mCookies;
	}

	public void setCookies(FaceBookCookie mCookies) {
		this.mCookies = mCookies;
	}

	public long getLastPost() {
		return mLastPost;
	}

	public void setLastPost(long mLastPost) {
		this.mLastPost = mLastPost;
	}

	public long getCookiesExpires() {
		return mCookiesExpires;
	}

	public void setCookiesExpires(long mCookiesExpires) {
		this.mCookiesExpires = mCookiesExpires;
	}

	public AccountProxy getProxy() {
		return mProxy;
	}

	public void setProxy(AccountProxy mProxy) {
		this.mProxy = mProxy;
	}

	public void getAcceToken(final OnRequestListnener listener) {
		final ArrayList<BasicNameValuePair> liHeaders = new ArrayList<BasicNameValuePair>();
		// liHeaders.add(new BasicNameValuePair("Cookie", this.getCookies()
		// .getCookieString()));
		liHeaders.add(new BasicNameValuePair("Accept-Language", "en;q=0.8"));
		FaceBookHTTPRequest
				.getRequestHeader(
						"https://www.facebook.com/dialog/oauth?client_id=145634995501895&redirect_uri=https://www.facebook.com/connect/login_success.html&response_type=token&display=popup&scope=user_about_me,user_groups,user_friends,user_likes,manage_pages",
						HttpMethod.GET, null, this, liHeaders,
						new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "header111 response " + response);
								if (response == null) {
									return;
								}
								if (response.contains("access_token=")
										&& response.contains("expires_in=")) {
									String acceToken = response.substring(
											response.indexOf("access_token=") + 13,
											response.indexOf("&", response
													.indexOf("access_token=")));
									FaceBookAccount.this.mToken = acceToken;

									String exprires = response.substring(response
											.indexOf("expires_in=") + 11);
									FaceBookAccount.this.mTokenExpires = System
											.currentTimeMillis()
											+ (Long.valueOf(exprires) - 600);
									Log.v(TAG, "header111 acceToken "
											+ acceToken + "---" + exprires);
									listener.onSuccess(response);
								} else {
									listener.onFailed(ErrorCode.GET_TOKEN_ERROR);
								}
							}

						},false);
	}

	public void getAccountInfors(final OnRequestListnener listnener) {
		getToken(new OnRequestListnener() {

			@Override
			public void onSuccess(String response) {
				// TODO Auto-generated method stub
				final String url = "https://graph.facebook.com/me?access_token="
						+ mToken;
				FaceBookHTTPRequest.getRequestText(url, HttpMethod.GET, null,
						FaceBookAccount.this, null, new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "infor response =" + response);
								try {
									JSONObject jsonObject = new JSONObject(
											response);
									FaceBookAccount.this.mID = jsonObject
											.getString("id");
									FaceBookAccount.this.mUserName = jsonObject
											.getString("name");
									listnener.onSuccess(response);
								} catch (JSONException e) {
									// TODO Auto-generated catch block
									listnener
											.onFailed(ErrorCode.JSON_PARSE_ERROR);
									e.printStackTrace();
								}
							}
						},false);
			}

			@Override
			public void onFailed(int errorCode) {
				// TODO Auto-generated method stub
				listnener.onFailed(errorCode);
			}
		});
	}

	public void getGroupsInfor(final OnRequestListnener listnener,
			final Handler handler, final TimeOutRunable timeRunable) {
		getToken(new OnRequestListnener() {

			@Override
			public void onSuccess(String response) {
				// TODO Auto-generated method stub
				String url = "https://graph.facebook.com/me/groups?fields=name,id,unread&&access_token="
						+ mToken;
				FaceBookHTTPRequest.getRequestText(url, HttpMethod.GET, null,
						FaceBookAccount.this, null, new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "infor response =" + response);
								listnener.onSuccess(response);
								handler.removeCallbacks(timeRunable);
							}
						},false);
			}

			@Override
			public void onFailed(int errorCode) {
				// TODO Auto-generated method stub
				listnener.onFailed(errorCode);
			}
		});
	}

	public void getLikes(final OnRequestListnener listnener,
			final Handler handler, final TimeOutRunable timeRunable) {
		getToken(new OnRequestListnener() {

			@Override
			public void onSuccess(String response) {
				// TODO Auto-generated method stub
				String url = "https://graph.facebook.com/me/likes?limit=5000&fields=id,name,category,likes,can_post&&access_token="
						+ mToken;
				FaceBookHTTPRequest.getRequestText(url, HttpMethod.GET, null,
						FaceBookAccount.this, null, new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "infor response =" + response);
								listnener.onSuccess(response);
								handler.removeCallbacks(timeRunable);
							}
						},false);
			}

			@Override
			public void onFailed(int errorCode) {
				// TODO Auto-generated method stub
				listnener.onFailed(errorCode);
			}
		});
	}

	public void getMyPages(final OnRequestListnener listnener,
			final Handler handler, final TimeOutRunable timeRunable) {
		getToken(new OnRequestListnener() {

			@Override
			public void onSuccess(String response) {
				// TODO Auto-generated method stub
				String url = "https://graph.facebook.com/me/accounts?fields=id,name&&access_token="
						+ mToken;
				FaceBookHTTPRequest.getRequestText(url, HttpMethod.GET, null,
						FaceBookAccount.this, null, new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "infor response =" + response);
								listnener.onSuccess(response);
								handler.removeCallbacks(timeRunable);
							}
						},false);
			}

			@Override
			public void onFailed(int errorCode) {
				// TODO Auto-generated method stub
				listnener.onFailed(errorCode);
			}
		});
	}

	public void getFriendsInfor(final OnRequestListnener listnener,
			final Handler handler, final TimeOutRunable timeRunable) {
		getToken(new OnRequestListnener() {

			@Override
			public void onSuccess(String response) {
				// TODO Auto-generated method stub
				String url = "https://graph.facebook.com/me/friends?fields=name,id&&access_token="
						+ mToken;
				FaceBookHTTPRequest.getRequestText(url, HttpMethod.GET, null,
						FaceBookAccount.this, null, new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "infor response =" + response);
								listnener.onSuccess(response);
								handler.removeCallbacks(timeRunable);
							}
						},false);
			}

			@Override
			public void onFailed(int errorCode) {
				// TODO Auto-generated method stub
				listnener.onFailed(errorCode);
			}
		});
	}

	public void getMembersInGroup(final String groupID,
			final OnRequestListnener listnener, final Handler handler,
			final TimeOutRunable timeRunable) {

		getToken(new OnRequestListnener() {

			@Override
			public void onSuccess(String response) {
				// TODO Auto-generated method stub
				String url = "https://graph.facebook.com/" + groupID
						+ "/members?access_token=" + mToken;
				FaceBookHTTPRequest.getRequestText(url, HttpMethod.GET, null,
						FaceBookAccount.this, null, new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "infor response =" + response);
								listnener.onSuccess(response);
								handler.removeCallbacks(timeRunable);
							}
						},false);
			}

			@Override
			public void onFailed(int errorCode) {
				// TODO Auto-generated method stub
				listnener.onFailed(errorCode);
			}
		});
	}

	public void setLanguage(String dasg, String lang) {

		String url = "https://www.facebook.com/ajax/settings/account/language.php";
		ArrayList<BasicNameValuePair> listParams = new ArrayList<BasicNameValuePair>();
		listParams.add(new BasicNameValuePair("fb_dtsg", dasg));
		listParams.add(new BasicNameValuePair("new_language", lang));
		listParams.add(new BasicNameValuePair("__user", this.mID));
		listParams.add(new BasicNameValuePair("__a", "1"));
		FaceBookHTTPRequest.getRequestText(url, HttpMethod.POST, listParams,
				this, null, new OnHttpResponse() {

					@Override
					public void onResponse(String response) {
						// TODO Auto-generated method stub
						Log.v(TAG, "change language response =" + response);
					}
				},false);
	}

	public void GetFBDTSG(final OnRequestListnener listnener) {
		getToken(new OnRequestListnener() {

			@Override
			public void onSuccess(String response) {
				String url = "https://m.facebook.com/photos/upload/";
				ArrayList<BasicNameValuePair> liHeaders = new ArrayList<BasicNameValuePair>();
				// liHeaders.add(new BasicNameValuePair("Cookie",
				// this.getCookies()
				// .getCookieString()));
				FaceBookHTTPRequest.getRequestText(url, HttpMethod.GET, null,
						FaceBookAccount.this, liHeaders, new OnHttpResponse() {

							@Override
							public void onResponse(String response) {
								// TODO Auto-generated method stub
								Log.v(TAG, "onresponse = " + response);
								Document doc = Jsoup.parse(response);
								Element node = doc.getElementsByAttributeValue(
										"name", "fb_dtsg").first();
								String ndtsg = node.attr("value");
								Log.v("TAG", "fbndtsg= " + ndtsg);
								listnener.onSuccess(ndtsg);
							}
						},false);
			}

			@Override
			public void onFailed(int errorCode) {
				// TODO Auto-generated method stub

			}
		});
	}

	public static ArrayList<FaceBookAccount> getListAccountFile(Context context) {
		ArrayList<FaceBookAccount> result = new ArrayList<FaceBookAccount>();
		File sdcard = Environment.getExternalStorageDirectory();
		File root = new File(sdcard, FPSConfig.DATA_FOLDER);
		File directory = new File(root.getAbsolutePath() + "/"
				+ FPSConfig.ACCOUNTS_FOLDER);
		if (!directory.exists()) {
			Log.v(TAG, directory.getAbsolutePath() + "exists");
			return result;
		}
		// get all the files from a directory
		File[] fList = directory.listFiles();
		for (File file : fList) {
			if (file.isFile() && file.getName().endsWith(".acc")) {
				try {
					result.add(new FaceBookAccount(context, Utilities
							.readFile(file)));
				} catch (XmlPullParserException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Utilities.showError(ErrorCode.XML_PARSER_ERROR, context);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					Utilities.showError(ErrorCode.IO_EXCEPTION_ERROR, context);
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	public FaceBookAccount(Context context, String xml)
			throws XmlPullParserException, IOException {
		XmlPullParserFactory factory = null;
		factory = XmlPullParserFactory.newInstance();
		factory.setNamespaceAware(true);
		XmlPullParser xpp = factory.newPullParser();
		xpp.setInput(new StringReader(xml));
		int eventType = xpp.getEventType();
		int i = 0;
		while (eventType != XmlPullParser.END_DOCUMENT) {
			if (eventType == XmlPullParser.START_TAG) {
				// Log.v(TAG, "name= " + xpp.getName() + "    " +
				// xpp.nextText());
				if (xpp.getName().equals("ID")) {
					this.mID = xpp.nextText();
				}
				if (xpp.getName().equals("Token")) {
					this.mToken = xpp.nextText();
				}
				if (xpp.getName().equals("TokenExpires")) {
					this.mTokenExpires = Long.valueOf(xpp.nextText());
				}
				if (xpp.getName().equals("UserName")) {
					this.mUserName = xpp.nextText();
				}
				if (xpp.getName().equals("Cookies")) {
					this.mCookies = new FaceBookCookie(xpp.nextText());
				}
				if (xpp.getName().equals("LastPost")) {
					this.mLastPost = Long.valueOf(xpp.nextText());
				}
				if (xpp.getName().equals("CookiesExpires")) {
					this.mCookiesExpires = Long.valueOf(xpp.nextText());
				}
			} else {
				if (eventType == XmlPullParser.END_TAG
						&& xpp.getName().equals("FaceBookAccount")) {
					return;
				}
			}
			eventType = xpp.next();
		}
	}

	public FaceBookAccount() {
		// TODO Auto-generated constructor stub
	}

	public void save(Context context) {
		XmlSerializer serializer = Xml.newSerializer();
		StringWriter writer = new StringWriter();
		try {
			serializer.setOutput(writer);
			serializer.startTag("", "FacebookAccount");

			serializer.startTag("", "ID");
			serializer.text(this.mID);
			serializer.endTag("", "ID");

			serializer.startTag("", "Token");
			serializer.text(this.mToken);
			serializer.endTag("", "Token");

			serializer.startTag("", "TokenExpires");
			serializer.text(String.valueOf(this.getTokenExpires()));
			serializer.endTag("", "TokenExpires");

			serializer.startTag("", "UserName");
			serializer.text(String.valueOf(this.getUserName()));
			serializer.endTag("", "UserName");

			serializer.startTag("", "Cookies");
			serializer
					.text(String.valueOf(this.getCookies().getCookieString()));
			serializer.endTag("", "Cookies");

			serializer.startTag("", "LastPost");
			serializer.text(String.valueOf(this.getLastPost()));
			serializer.endTag("", "LastPost");

			serializer.startTag("", "CookiesExpires");
			serializer.text(String.valueOf(this.getCookiesExpires()));
			serializer.endTag("", "CookiesExpires");

			serializer.endTag("", "FacebookAccount");
			serializer.endDocument();
			Utilities.startSaveFile(FPSConfig.ACCOUNTS_FOLDER, this.mID
					+ ".acc", context, writer.toString().getBytes());
		} catch (IllegalArgumentException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalStateException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		try {
			serializer.setOutput(writer);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void PostAPrivateMessage(String dtsg, String targetID,
			FaceBookMessage message, final OnPostResultListener listener) {
		final FaceBookPostResult result = new FaceBookPostResult();
		result.setOK(false);
		result.setStatus("Failure (Invalid Params)");
		if (dtsg == null || dtsg.isEmpty())
			listener.onResult(result);
		if (targetID == null || targetID.isEmpty())
			listener.onResult(result);
		result.setStatus("Failure");
		String url = "https://m.facebook.com/messages/send/";
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("fb_dtsg", dtsg));
		params.add(new BasicNameValuePair("body",  message.getText()));
		params.add(new BasicNameValuePair("ids["+targetID+"]", targetID));
		// String data = String.Format("fb_dtsg={0}&body={1}&ids[{2}]={2}",
		// dtsg,
		// msg.MsgText, targetID);
		// String returnURL = HttpRequest.GetRequestText(url,
		// WebRequestMethods.Http.Post, Encoding.ASCII.GetBytes(data), "",
		// this.Cookies, "", WebProxy(), false, true);
		FaceBookHTTPRequest.getRequestHeader(url, HttpMethod.POST, params, this,
				null, new OnHttpResponse() {
					@Override
					public void onResponse(String response) {
						// TODO Auto-generated method stub
						Log.v(TAG, " post message response :" + response);
						if (response.endsWith("request_type=send_success&_rdr")) {
							result.setOK(true);
							result.setStatus("sent");
						}
						listener.onResult(result);
					}
				},false);
	}

	public void postToWallID(final String dtsg, final String id,
			final FaceBookMessage msg, final OnPostResultListener listener) {
		final FaceBookPostResult result = new FaceBookPostResult();
		result.setOK(false);
		result.setStatus("Failure (Invalid Params)");
		if (dtsg != null && dtsg.isEmpty())
			listener.onResult(result);
		if (id != null && id.isEmpty())
			listener.onResult(result);
		result.setStatus("Failure");
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("__a", "1"));
		params.add(new BasicNameValuePair("xhpc_composerid", "u_jsonp_2_n"));
		params.add(new BasicNameValuePair("fb_dtsg", dtsg));
		params.add(new BasicNameValuePair("xhpc_message", msg.getText()));
		params.add(new BasicNameValuePair("xhpc_targetid", id));
		if (msg.getLink() != null && msg.getLink().isEmpty()) {
			params.add(new BasicNameValuePair("attachment[params][url]", msg
					.getLink()));
			params.add(new BasicNameValuePair("attachment[params][images][0]",
					msg.getImg()));
			params.add(new BasicNameValuePair("attachment[params][title]", msg
					.getTitle()));
			params.add(new BasicNameValuePair("attachment[params][summary]",
					msg.getDesc()));
			params.add(new BasicNameValuePair("attachment[type]", "100"));
			params.add(new BasicNameValuePair("hide_object_attachment", "0"));
		} else if (msg.getAttStr() != null && msg.getAttStr().isEmpty()) {
			// data += msg.AttStr;
		}
		String url = "https://www.facebook.com/ajax/updatestatus.php";
		FaceBookHTTPRequest.getRequestText(url, HttpMethod.POST, params,
				FaceBookAccount.this, null, new OnHttpResponse() {

					@Override
					public void onResponse(String response) {
						// TODO Auto-generated method stub
						Log.v(TAG, " post message response :" + response);
						String postID = Utilities.substring(response,
								"message_id=", '&');
						if (postID != "") {
							result.setPostID(postID);
							result.setOK(true);
							result.setStatus("Posted");
							listener.onResult(result);
						} else if (response.contains("pending approval")) {
							result.setStatus("Pending");
							result.setOK(true);
							listener.onResult(result);
						} else {
							String errSum = Utilities.substring(response,
									"\"errorSummary\":\"", '"');
							if (errSum != "") {
								String errDesc = Utilities.substring(response,
										"\"errorDescription\":\"", '"');
								result.setStatus("Failure ("
										+ (errDesc != "" ? errDesc : errSum)
										+ ")");
							}
						}
					}
				},false);

	}
}
